home *** CD-ROM | disk | FTP | other *** search
- /*
- * procMisc.c --
- *
- * Misc. routines to get and set process state.
- *
- * Copyright 1986 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /sprite/src/kernel/proc/RCS/procMisc.c,v 9.16 91/04/29 16:31:46 kupfer Exp $ SPRITE (Berkeley)";
- #endif /* not lint */
-
- #include <sprite.h>
- #include <proc.h>
- #include <status.h>
- #include <sync.h>
- #include <sched.h>
- #include <sig.h>
- #include <stdlib.h>
- #include <list.h>
- #include <string.h>
- #include <procInt.h>
- #include <rpc.h>
- #include <dbg.h>
- #include <vm.h>
- #include <ctype.h>
- #include <fscache.h>
- #include <fsutil.h>
- #include <rpcClient.h>
- #include <rpcServer.h>
- #include <procServer.h>
- #include <fsrmt.h>
- #include <bstring.h>
- #include <stdio.h>
-
- #define min(a,b) ((a) < (b) ? (a) : (b))
- /*
- * Procedures internal to this file
- */
-
- static ReturnStatus GetRemotePCB _ARGS_((int hostID, Proc_PID pid,
- Proc_PCBInfo *pcbPtr, char *argString));
- static void FillPCBInfo _ARGS_((Proc_ControlBlock *pcbPtr,
- Proc_PCBInfo *statusInfoPtr));
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_Init --
- *
- * Called during startup to initialize data structures.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Process table initialized, debug list initialized, locks initialized.
- *
- *----------------------------------------------------------------------
- */
-
- void
- Proc_Init()
- {
- ProcInitTable();
- ProcDebugInit();
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_GetPCBInfo --
- *
- * Returns the process control blocks for the specified processes
- * on the specified host. If firstPid is equal to PROC_MY_PID
- * and the hostID is PROC_MY_HOSTID, then the PCB for the current
- * process is returned. Otherwise PCBs for all processes in the
- * range firstPid to lastPid on host hostID are returned. Only
- * the index portions of the processIDs for firstPid and lastPid
- * are relevant.
- *
- * Results:
- * SYS_INVALID_ARG - firstPid was < 0, firstPid > lastPid
- * SYS_ARG_NOACCESS - The buffers to store the pcbs in were not
- * accessible.
- * *trueNumBuffers is set to be the actual number of
- * PCBs returned which can be less than the number requested if
- * lastPid - firstPid is greater than the maximum PCBs available.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- /*
- * Macro to fix up ticks for a process control block.
- */
- #define TICKS_TO_TIME(pcbEntry) \
- Timer_TicksToTime(pcbEntry.kernelCpuUsage.ticks, \
- &pcbEntry.kernelCpuUsage.time); \
- Timer_TicksToTime(pcbEntry.userCpuUsage.ticks, \
- &pcbEntry.userCpuUsage.time); \
- Timer_TicksToTime(pcbEntry.childKernelCpuUsage.ticks, \
- &pcbEntry.childKernelCpuUsage.time); \
- Timer_TicksToTime(pcbEntry.childUserCpuUsage.ticks, \
- &pcbEntry.childUserCpuUsage.time);
-
-
- ReturnStatus
- Proc_GetPCBInfo(firstPid, lastPid, hostID, infoSize, bufferPtr,
- argsPtr, trueNumBuffersPtr)
- Proc_PID firstPid; /* First pid to get info for. */
- Proc_PID lastPid; /* Last pid to get info for. */
- int hostID; /* Host ID to get info for. */
- int infoSize; /* Size of structure */
- Address bufferPtr; /* Pointer to buffers. */
- Proc_PCBArgString *argsPtr; /* Pointer to argument strings. */
- int *trueNumBuffersPtr; /* The actual number of buffers
- used.*/
- {
- register Proc_ControlBlock *procPtr = (Proc_ControlBlock *) NIL;
- int i, j;
- char argString[PROC_PCB_ARG_LENGTH];
- Proc_ControlBlock pcbEntry;
- Boolean remote = FALSE;
- Proc_PID processID = firstPid;
- ReturnStatus status = SUCCESS;
- Proc_PCBInfo statusInfo;
- int bytesToCopy;
-
-
- if (firstPid != PROC_MY_PID) {
- firstPid &= PROC_INDEX_MASK;
- lastPid &= PROC_INDEX_MASK;
- if ((firstPid > lastPid) ||
- ((firstPid == PROC_MY_PID) && hostID != PROC_MY_HOSTID)) {
- return(GEN_INVALID_ARG);
- }
- }
- if (bufferPtr == USER_NIL) {
- return (SYS_ARG_NOACCESS);
- }
- if (hostID != PROC_MY_HOSTID &&
- (hostID <= 0 || hostID > NET_NUM_SPRITE_HOSTS)) {
- return(GEN_INVALID_ARG);
- }
-
- bytesToCopy = min(sizeof(Proc_PCBInfo), infoSize);
- /*
- * Determine whether to get process table entries for this machine.
- * Currently, the information for this machine is returned unless
- * another machine is explicitly specified; i.e., migrated processes
- * get information for their current machine rather than their home.
- */
-
- if (hostID == PROC_MY_HOSTID) {
- #ifdef FORWARD_MIGRATED_GET_PCBS
- procPtr = Proc_GetCurrentProc();
- Proc_Lock(procPtr);
- if (procPtr->genFlags & PROC_FOREIGN) {
- hostID = procPtr->peerHostID;
- processID = procPtr->peerHostID;
- remote = TRUE;
- }
- Proc_Unlock(procPtr);
- #endif /* FORWARD_MIGRATED_GET_PCBS */
- } else if (hostID != rpc_SpriteID) {
- remote = TRUE;
- }
-
- if (firstPid == PROC_MY_PID) {
- /*
- * Return PCB for the current process.
- */
- procPtr = Proc_GetCurrentProc();
- if (!remote) {
- bcopy((Address)procPtr, (Address)&pcbEntry,
- sizeof (Proc_ControlBlock));
- TICKS_TO_TIME(pcbEntry);
- FillPCBInfo(&pcbEntry, &statusInfo);
- } else {
- status = GetRemotePCB(hostID, processID, &statusInfo,
- argString);
- if (status != SUCCESS) {
- return(status);
- }
- }
- if (Proc_ByteCopy(FALSE, bytesToCopy,
- (Address)&statusInfo, (Address) bufferPtr) != SUCCESS) {
- return(SYS_ARG_NOACCESS);
- }
- if (argsPtr != (Proc_PCBArgString *) USER_NIL) {
- if (!remote) {
- if (procPtr->argString != (Address) NIL) {
- (void) strncpy(argString, procPtr->argString,
- PROC_PCB_ARG_LENGTH - 1);
- argString[PROC_PCB_ARG_LENGTH - 1] = '\0';
- } else {
- argString[0] = '\0';
- }
- }
- if (Proc_ByteCopy(FALSE, PROC_PCB_ARG_LENGTH, argString,
- (Address) argsPtr) != SUCCESS) {
- return(SYS_ARG_NOACCESS);
- }
- }
- } else {
-
- /*
- * Return PCB for all processes or enough to fill all of
- * the buffers, whichever comes first.
- */
-
-
- for (i = firstPid, j = 0;
- i <= lastPid;
- i++, j++, (Address) bufferPtr += infoSize) {
- if (!remote) {
- if (i >= proc_MaxNumProcesses) {
- break;
- }
- procPtr = Proc_GetPCB(i);
- if (procPtr == (Proc_ControlBlock *) NIL) {
- panic("Proc_GetInfo: procPtr == NIL!\n");
- status = FAILURE;
- break;
- }
- bcopy((Address)procPtr, (Address)&pcbEntry,
- sizeof (Proc_ControlBlock));
-
- TICKS_TO_TIME(pcbEntry);
- FillPCBInfo(&pcbEntry, &statusInfo);
- } else {
- status = GetRemotePCB(hostID, (Proc_PID) i, &statusInfo,
- argString);
- if (status != SUCCESS) {
- /*
- * Break if we hit an error. The typical error condition
- * is to hit an invalid process ID, which happens since
- * we don't know proc_MaxNumProcesses on the other
- * machine. Instead, we convert GEN_INVALID_ARG to
- * SUCCESS and return what we found so far.
- */
- if (status == GEN_INVALID_ARG) {
- status = SUCCESS;
- }
- break;
- }
- }
- if (Proc_ByteCopy(FALSE, bytesToCopy,
- (Address)&statusInfo, (Address) bufferPtr) != SUCCESS) {
- return(SYS_ARG_NOACCESS);
- }
- if (argsPtr != (Proc_PCBArgString *) USER_NIL) {
- if (!remote) {
- if (procPtr->argString != (Address) NIL) {
- (void) strncpy(argString, procPtr->argString,
- PROC_PCB_ARG_LENGTH - 1);
- argString[PROC_PCB_ARG_LENGTH - 1] = '\0';
- } else {
- argString[0] = '\0';
- }
- }
- if (Proc_ByteCopy(FALSE, PROC_PCB_ARG_LENGTH, argString,
- (Address) &(argsPtr[j])) != SUCCESS) {
- return(SYS_ARG_NOACCESS);
- }
- }
- }
-
- if (trueNumBuffersPtr != USER_NIL) {
- if (Proc_ByteCopy(FALSE, sizeof(j), (Address) &j,
- (Address) trueNumBuffersPtr) != SUCCESS) {
- return(SYS_ARG_NOACCESS);
- }
- }
- }
-
- return(status);
- }
-
-
-
- /*
- * Define some constants used to distinguish RPC sub-commands.
- */
- #define GET_PCB 1
- #define GET_SEG_INFO 2
-
- /*
- *----------------------------------------------------------------------
- *
- * GetRemotePCB --
- *
- * Perform an RPC to get a process control block from another host.
- *
- * Results:
- * The return status from the RPC is returned.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static ReturnStatus
- GetRemotePCB(hostID, pid, pcbPtr, argString)
- int hostID; /* Host to send RPC to. */
- Proc_PID pid; /* index of PCB to obtain. */
- Proc_PCBInfo *pcbPtr; /* Place to return PCB data. */
- char *argString; /* Place to return argument string. */
- {
- Rpc_Storage storage;
- ReturnStatus status;
- int request;
-
- request = GET_PCB;
- storage.requestParamPtr = (Address)&request;
- storage.requestParamSize = sizeof(request);
- storage.requestDataPtr = (Address)&pid;
- storage.requestDataSize = sizeof(Proc_PID);
- storage.replyParamPtr = (Address)pcbPtr;
- storage.replyParamSize = sizeof(Proc_PCBInfo);
- storage.replyDataPtr = (Address)argString;
- storage.replyDataSize = PROC_PCB_ARG_LENGTH;
-
- status = Rpc_Call(hostID, RPC_PROC_GETPCB, &storage);
- if (status == SUCCESS && storage.replyDataSize == 0) {
- argString[0] = '\0';
- }
- return(status);
-
- }
- /*
- *----------------------------------------------------------------------
- *
- * Proc_GetRemoteSegInfo --
- *
- * Perform an RPC to get info for a VM segment control from another host.
- *
- * Results:
- * The return status from the RPC is returned.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Proc_GetRemoteSegInfo(hostID, segNum, segInfoPtr)
- int hostID; /* Host to send RPC to. */
- int segNum; /* index of segment to obtain. */
- Vm_SegmentInfo *segInfoPtr; /* Place to return segment data. */
- {
- Rpc_Storage storage;
- ReturnStatus status;
- int request;
-
- request = GET_SEG_INFO;
- storage.requestParamPtr = (Address)&request;
- storage.requestParamSize = sizeof(request);
- storage.requestDataPtr = (Address)&segNum;
- storage.requestDataSize = sizeof(int);
- storage.replyParamPtr = (Address)segInfoPtr;
- storage.replyParamSize = sizeof(Vm_SegmentInfo);
- storage.replyDataPtr = (Address)NIL;
- storage.replyDataSize = 0;
-
- status = Rpc_Call(hostID, RPC_PROC_GETPCB, &storage);
- return(status);
-
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FillPCBInfo --
- *
- * Fills in a Proc_PCBInfo structure from the contents of a
- * control block.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- FillPCBInfo(pcbPtr, statusInfoPtr)
- Proc_ControlBlock *pcbPtr; /* Ptr to pcb to convert */
- Proc_PCBInfo *statusInfoPtr; /* Structure to fill in */
- {
- int i;
-
- statusInfoPtr->processor = pcbPtr->processor;
- statusInfoPtr->state = pcbPtr->state;
- statusInfoPtr->genFlags = pcbPtr->genFlags;
- statusInfoPtr->processID = pcbPtr->processID;
- statusInfoPtr->parentID = pcbPtr->parentID;
- statusInfoPtr->familyID = pcbPtr->familyID;
- statusInfoPtr->userID = pcbPtr->userID;
- statusInfoPtr->effectiveUserID = pcbPtr->effectiveUserID;
- statusInfoPtr->event = pcbPtr->event;
- statusInfoPtr->billingRate = pcbPtr->billingRate;
- statusInfoPtr->recentUsage = pcbPtr->recentUsage;
- statusInfoPtr->weightedUsage = pcbPtr->weightedUsage;
- statusInfoPtr->unweightedUsage = pcbPtr->unweightedUsage;
- statusInfoPtr->kernelCpuUsage = pcbPtr->kernelCpuUsage.time;
- statusInfoPtr->userCpuUsage = pcbPtr->userCpuUsage.time;
- statusInfoPtr->childKernelCpuUsage = pcbPtr->childKernelCpuUsage.time;
- statusInfoPtr->childUserCpuUsage = pcbPtr->childUserCpuUsage.time;
- statusInfoPtr->numQuantumEnds = pcbPtr->numQuantumEnds;
- statusInfoPtr->numWaitEvents = pcbPtr->numWaitEvents;
- statusInfoPtr->schedQuantumTicks = pcbPtr->schedQuantumTicks;
- for(i = 0; i < VM_NUM_SEGMENTS; i++) {
- if (pcbPtr->vmPtr != (Vm_ProcInfo *) NIL &&
- pcbPtr->vmPtr->segPtrArray[i] != (Vm_Segment *) NIL) {
- statusInfoPtr->vmSegments[i] =
- (Vm_SegmentID) pcbPtr->vmPtr->segPtrArray[i]->segNum;
- } else {
- statusInfoPtr->vmSegments[i] = (Vm_SegmentID) -1;
- }
- }
- statusInfoPtr->sigHoldMask = pcbPtr->sigHoldMask;
- statusInfoPtr->sigPendingMask = pcbPtr->sigPendingMask;
- for(i = 0; i < SIG_NUM_SIGNALS; i++) {
- statusInfoPtr->sigActions[i] = pcbPtr->sigActions[i];
- }
- statusInfoPtr->peerHostID = pcbPtr->peerHostID;
- statusInfoPtr->peerProcessID = pcbPtr->peerProcessID;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_RpcGetPCB --
- *
- * Stub to handle a remote request for a PCB or Vm_Segment.
- *
- * Results:
- * Status of reply:
- * GEN_INVALID_ARG - index into table of process control blocks is
- * invalid, or segment is invalid.
- * SUCCESS - information is returned.
- *
- * SUCCESS is passed to the caller on this machine.
- *
- * Side effects:
- * Reply is sent.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- Proc_RpcGetPCB(srvToken, clientID, command, storagePtr)
- ClientData srvToken; /* Handle on server process passed to
- * Rpc_Reply */
- int clientID; /* Sprite ID of client host */
- int command; /* Command identifier */
- register Rpc_Storage *storagePtr; /* The request fields refer to the
- * request buffers and also indicate
- * the exact amount of data in the
- * request buffers. The reply fields
- * are initialized to NIL for the
- * pointers and 0 for the lengths.
- * This can be passed to Rpc_Reply */
- {
- ReturnStatus status = SUCCESS;
- Proc_PID *pidPtr;
- Rpc_ReplyMem *replyMemPtr;
- Proc_PCBInfo *pcbPtr;
- Proc_ControlBlock *procPtr = (Proc_ControlBlock *) NIL;
- Proc_ControlBlock pcb;
- int *segNumPtr;
- Vm_SegmentInfo *segInfoPtr;
- int *requestPtr;
-
- requestPtr = (int *) storagePtr->requestParamPtr;
- if (*requestPtr == GET_SEG_INFO) {
- segNumPtr = (int *) storagePtr->requestDataPtr;
- segInfoPtr = (Vm_SegmentInfo *) malloc(sizeof (Vm_SegmentInfo));
- status = Vm_EncapSegInfo(*segNumPtr, segInfoPtr);
- storagePtr->replyParamPtr = (Address) segInfoPtr;
- storagePtr->replyParamSize = sizeof(Vm_SegmentInfo);
- goto done;
- } else if (*requestPtr == GET_PCB) {
- pidPtr = (Proc_PID *) storagePtr->requestDataPtr;
- if (*pidPtr >= proc_MaxNumProcesses) {
- status = GEN_INVALID_ARG;
- } else {
- procPtr = Proc_GetPCB(*pidPtr);
- if (procPtr == (Proc_ControlBlock *) NIL) {
- panic("Proc_RpcGetPCB: found nil PCB!");
- status = FAILURE;
- }
- }
- if (status != SUCCESS) {
- Rpc_Reply(srvToken, status, storagePtr,
- (int(*)())NIL, (ClientData)NIL);
- return(SUCCESS);
- }
-
- bcopy((Address) procPtr, (Address) &pcb, sizeof (Proc_ControlBlock));
- TICKS_TO_TIME(pcb);
- pcbPtr = (Proc_PCBInfo *) malloc(sizeof (Proc_PCBInfo));
- storagePtr->replyParamPtr = (Address) pcbPtr;
- storagePtr->replyParamSize = sizeof(Proc_PCBInfo);
- FillPCBInfo(&pcb, pcbPtr);
-
- if (procPtr->argString != (Address) NIL) {
- storagePtr->replyDataSize = strlen(procPtr->argString) + 1;
- storagePtr->replyDataPtr = (Address) malloc(storagePtr->replyDataSize);
- (void) strcpy(storagePtr->replyDataPtr, procPtr->argString);
- } else {
- storagePtr->replyDataSize = 0;
- storagePtr->replyDataPtr = (Address) NIL;
- }
- }
- done:
- replyMemPtr = (Rpc_ReplyMem *) malloc(sizeof(Rpc_ReplyMem));
- replyMemPtr->paramPtr = storagePtr->replyParamPtr;
- replyMemPtr->dataPtr = storagePtr->replyDataPtr;
-
- Rpc_Reply(srvToken, status, storagePtr, Rpc_FreeMem,
- (ClientData) replyMemPtr);
- return(SUCCESS);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_GetResUsage --
- *
- * Returns the resource usage for a process.
- *
- * Results:
- * SYS_INVALID_ARG - buffer address was invalid.
- * PROC_INVALID_PID - The pid was out-of-range or specified a
- * non-existent process.
- * SYS_ARG_NOACCESS - The buffers to store the pcbs in were not
- * accessible.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Proc_GetResUsage(pid, bufferPtr)
- Proc_PID pid;
- Proc_ResUsage *bufferPtr;
- {
- register Proc_ControlBlock *procPtr;
- Proc_ResUsage resUsage;
- ReturnStatus status = SUCCESS;
-
- if (pid == PROC_MY_PID) {
- procPtr = Proc_GetEffectiveProc();
- if (procPtr == (Proc_ControlBlock *) NIL) {
- panic("Proc_GetResUsage: procPtr == NIL\n");
- }
- Proc_Lock(procPtr);
- } else {
- procPtr = Proc_LockPID(pid);
- if (procPtr == (Proc_ControlBlock *) NIL) {
- return (PROC_INVALID_PID);
- }
- }
-
- /*
- * Copy the information to the out parameters.
- */
-
- if (bufferPtr == USER_NIL) {
- status = SYS_INVALID_ARG;
- } else {
- Timer_TicksToTime(procPtr->kernelCpuUsage.ticks,
- &resUsage.kernelCpuUsage);
- Timer_TicksToTime(procPtr->userCpuUsage.ticks, &resUsage.userCpuUsage);
- Timer_TicksToTime(procPtr->childKernelCpuUsage.ticks,
- &resUsage.childKernelCpuUsage);
- Timer_TicksToTime(procPtr->childUserCpuUsage.ticks,
- &resUsage.childUserCpuUsage);
- resUsage.numQuantumEnds = procPtr->numQuantumEnds;
- resUsage.numWaitEvents = procPtr->numWaitEvents;
-
- if (Proc_ByteCopy(FALSE, sizeof(Proc_ResUsage),
- (Address) &resUsage, (Address) bufferPtr) != SUCCESS){
- status = SYS_ARG_NOACCESS;
- }
- }
- Proc_Unlock(procPtr);
- return(status);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_GetPriority --
- *
- * Returns the priority of a process.
- *
- * Results:
- * SYS_INVALID_ARG - priorityPtr address was invalid.
- * PROC_INVALID_PID - The pid was out-of-range or specified a
- * non-existent process.
- * SYS_ARG_NOACCESS - The buffer to store the priority was not
- * accessible.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Proc_GetPriority(pid, priorityPtr)
- Proc_PID pid; /* ID of process whose priority is to be returned. */
- int *priorityPtr; /* Priority returned by Proc_GetPriority. */
- {
- register Proc_ControlBlock *procPtr;
- ReturnStatus status = SUCCESS;
-
- if (pid == PROC_MY_PID) {
- procPtr = Proc_GetEffectiveProc();
- if (procPtr == (Proc_ControlBlock *) NIL) {
- panic("Proc_GetPriority: procPtr == NIL\n");
- }
- Proc_Lock(procPtr);
- } else {
- procPtr = Proc_LockPID(pid);
- if (procPtr == (Proc_ControlBlock *) NIL) {
- return (PROC_INVALID_PID);
- }
- }
-
- /*
- * Copy the information to the out parameter.
- */
-
- if (priorityPtr == USER_NIL) {
- status = SYS_INVALID_ARG;
- } else {
- if (Proc_ByteCopy(FALSE, sizeof(int),
- (Address) &(procPtr->billingRate),
- (Address) priorityPtr) != SUCCESS) {
- status = SYS_ARG_NOACCESS;
- }
- }
- Proc_Unlock(procPtr);
- return(status);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_SetPriority --
- *
- * Sets the priority for a process.
- *
- * Results:
- * PROC_INVALID_PID - The pid was out-of-range or specified a
- * non-existent process.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Proc_SetPriority(pid, priority, useFamily)
- Proc_PID pid; /* ID of process whose priority is to be set. */
- int priority; /* New scheduling priority for pid. */
- Boolean useFamily; /* If TRUE, use pid as the head of a process
- * family, and set the priority of every
- * process in the family. */
- {
- register Proc_ControlBlock *procPtr;
- register Proc_PCBLink *procLinkPtr;
- List_Links *familyList;
- int userID;
- ReturnStatus status;
-
- if (priority > PROC_MAX_PRIORITY) {
- priority = PROC_MAX_PRIORITY;
- } else if (priority < PROC_MIN_PRIORITY) {
- priority = PROC_MIN_PRIORITY;
- }
-
- if (useFamily) {
- /*
- * Set priorities of processes in family.
- */
- status = Proc_LockFamily((int) pid, &familyList, &userID);
- if (status != SUCCESS) {
- return(status);
- }
- if (!Proc_HasPermission(userID)) {
- Proc_UnlockFamily((int) pid);
- return(PROC_UID_MISMATCH);
- }
- LIST_FORALL(familyList, (List_Links *) procLinkPtr) {
- procPtr = procLinkPtr->procPtr;
- Proc_Lock(procPtr);
- procPtr->billingRate = priority;
- Proc_Unlock(procPtr);
- }
- Proc_UnlockFamily((int) pid);
- } else {
- /*
- * Set the individual process's priority.
- */
- if (pid == PROC_MY_PID) {
- procPtr = Proc_GetEffectiveProc();
- Proc_Lock(procPtr);
- } else {
- procPtr = Proc_LockPID(pid);
- if (procPtr == (Proc_ControlBlock *) NIL) {
- return (PROC_INVALID_PID);
- }
- if (!Proc_HasPermission(procPtr->effectiveUserID)) {
- Proc_Unlock(procPtr);
- return(PROC_UID_MISMATCH);
- }
- }
- procPtr->billingRate = priority;
- Proc_Unlock(procPtr);
- }
-
- return(SUCCESS);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_Profile --
- *
- * Starts profiling the memory accesses of the current process.
- *
- * Results:
- * SUCCESS - always returned for now.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- /*ARGSUSED*/
- ReturnStatus
- Proc_Profile(shiftSize, lowPC, highPC, interval, counterArray)
- int shiftSize; /* # of bits to shift the PC to the right. */
- int lowPC; /* The lowest PC to profile. */
- int highPC; /* The highest PC to profile. */
- Time interval; /* The time interval at which the PC is sampled. */
- int counterArray[]; /* Counters used to count instruction executions. */
- {
- return(SUCCESS);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_Dump --
- *
- * Prints out an abbreviated proc table for debugging purposes.
- *
- * Results:
- * SUCCESS.
- *
- * Side effects:
- * Prints stuff to screen.
- *
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Proc_Dump()
- {
- int i;
- Proc_ControlBlock *pcbPtr;
-
- printf("\n%8s %5s %10s %10s %8s %8s %s\n",
- "ID", "wtd", "user", "kernel", "event", "state", "name");
-
- for (i = 0; i < proc_MaxNumProcesses; i++) {
- pcbPtr = proc_PCBTable[i];
- if (pcbPtr->state != PROC_UNUSED) {
- Proc_DumpPCB(pcbPtr);
- }
- }
- return(SUCCESS);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_DumpPCB --
- *
- * Prints out the contents of a PCB for debugging purposes.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Prints stuff to the screen.
- *
- *----------------------------------------------------------------------
- */
-
- void
- Proc_DumpPCB(procPtr)
- Proc_ControlBlock *procPtr;
- {
-
- Time kernelTime, userTime;
-
- #define DEBUG_INDEX 0x9
-
- static char *states[] = {
- "unused",
- "running",
- "ready",
- "waiting",
- "exiting",
- "dead",
- "migrated",
- "new",
- "suspended",
- "debug",
- };
- Proc_State state;
-
- state = procPtr->state;
- switch (state) {
- case PROC_UNUSED:
- case PROC_RUNNING:
- case PROC_READY:
- case PROC_WAITING:
- case PROC_EXITING:
- case PROC_DEAD:
- case PROC_MIGRATED:
- case PROC_NEW:
- break;
- case PROC_SUSPENDED:
- /* If process is suspended for debugging print "debug" for its
- * state.
- */
- if (procPtr->genFlags & (PROC_DEBUGGED | PROC_ON_DEBUG_LIST)) {
- state = (Proc_State)DEBUG_INDEX;
- }
- break;
- default:
- printf("Warning: Proc_DumpPCB: process %x has invalid process state: %x.\n",
- procPtr->processID, state);
- return;
- }
- /*
- * A header describing the fields has already been printed.
- */
- Timer_TicksToTime(procPtr->userCpuUsage.ticks, &userTime);
- Timer_TicksToTime(procPtr->kernelCpuUsage.ticks, &kernelTime);
- printf("%8x %5d [%1d,%6d] [%1d,%6d] %8x %8s",
- procPtr->processID,
- procPtr->weightedUsage,
- userTime.seconds,
- userTime.microseconds,
- kernelTime.seconds,
- kernelTime.microseconds,
- procPtr->event,
- states[(int) state]);
- if (procPtr->argString != (Address) NIL) {
- char cmd[30];
- char *space;
-
- (void) strncpy(cmd, procPtr->argString, 30);
- space = strchr(cmd, ' ');
- if (space != (char *) NULL) {
- *space = '\0';
- }
- printf(" %s\n", cmd);
- } else {
- printf("\n");
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_KillAllProcesses --
- *
- * Send the kill signal to all processes in the proc table except for
- * the caller. If userProcsOnly is TRUE only send signals to user
- * processes.
- *
- * Results:
- * The number of runnable and waiting processes.
- *
- * Side effects:
- * The kill signal bit is set for all processes.
- *
- *----------------------------------------------------------------------
- */
- int
- Proc_KillAllProcesses(userProcsOnly)
- Boolean userProcsOnly; /* TRUE if only kill user processes. */
- {
- register int i;
- register Proc_ControlBlock *pcbPtr;
- Proc_ControlBlock *curProcPtr;
- int alive = 0;
-
- curProcPtr = Proc_GetActualProc();
-
- for (i = 0; i < proc_MaxNumProcesses; i++) {
- pcbPtr = proc_PCBTable[i];
- if (pcbPtr == curProcPtr || pcbPtr->state == PROC_UNUSED ||
- (userProcsOnly && !(pcbPtr->genFlags & PROC_USER))) {
- continue;
- }
- Proc_Lock(pcbPtr);
- if (pcbPtr->state == PROC_RUNNING ||
- pcbPtr->state == PROC_READY ||
- pcbPtr->state == PROC_WAITING ||
- pcbPtr->state == PROC_MIGRATED) {
- alive++;
- (void) Sig_SendProc(pcbPtr, SIG_KILL, 0, (Address)0);
- }
- Proc_Unlock(pcbPtr);
- }
-
- return(alive);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_WakeupAllProcesses --
- *
- * Wakup all waiting processes.
- *
- * Results:
- * None.
- *
- * Side effects:
- * All waiting processes are awakened.
- *
- *----------------------------------------------------------------------
- */
- void
- Proc_WakeupAllProcesses()
- {
- register int i;
- register Proc_ControlBlock *pcbPtr;
- Proc_ControlBlock *curProcPtr;
-
- curProcPtr = Proc_GetActualProc();
-
- for (i = 0; i < proc_MaxNumProcesses; i++) {
- pcbPtr = proc_PCBTable[i];
- if (pcbPtr == curProcPtr) {
- continue;
- }
- Proc_Lock(pcbPtr);
- if (pcbPtr->state != PROC_UNUSED) {
- Sync_WakeWaitingProcess(pcbPtr);
- }
- Proc_Unlock(pcbPtr);
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_HasPermission --
- *
- * See if the current process has permission to perform an operation on
- * a process with the given user id.
- *
- * Results:
- * TRUE if the current process has the same effective user id
- * as the given user id or the current process is super user.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- Boolean
- Proc_HasPermission(userID)
- int userID;
- {
- Proc_ControlBlock *procPtr;
-
- procPtr = Proc_GetEffectiveProc();
- return(procPtr->effectiveUserID == userID ||
- procPtr->effectiveUserID == PROC_SUPER_USER_ID);
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_DoForEveryProc --
- *
- * For every process in the process table, apply *booleanFuncPtr to it.
- * If that returns TRUE, apply *actionFuncPtr to it. This is done by
- * passing booleanFuncPtr to a monitored routine and having it
- * return an array of qualifying processes. There is a bit of a race
- * condition if something happens to any of those processes after the
- * list is returned, but in that case the process is ignored and the next
- * one is processed.
- *
- * IgnoreStatus indicates whether the routine should abort if
- * a non-SUCCESS status is returned by *actionFuncPtr.
- *
- * Results:
- * If anything "unexpected" happens, FAILURE will be returned, but in
- * general SUCCESS is returned. If numMatchedPtr is non-NIL, then
- * the number of processes matched is returned in *numMatchedPtr.
- *
- * Side effects:
- * The process table is locked temporarily. Otherwise, dependent on the
- * call-back procedures.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Proc_DoForEveryProc(booleanFuncPtr, actionFuncPtr, ignoreStatus, numMatchedPtr)
- Boolean (*booleanFuncPtr) _ARGS_((Proc_ControlBlock *pcbPtr));
- /* function to match */
- ReturnStatus (*actionFuncPtr)_ARGS_((Proc_PID pid));
- /* function to invoke on matches */
- Boolean ignoreStatus; /* do not abort if bad ReturnStatus */
- int *numMatchedPtr; /* number of matches in table, or NIL */
- {
- ReturnStatus status = SUCCESS;
- Proc_PID *pidArray;
- int max;
- int i;
- int numMatched;
-
- max = proc_MaxNumProcesses;
-
- pidArray = (Proc_PID *) malloc(sizeof(Proc_PID) * max);
- numMatched = ProcTableMatch(max, booleanFuncPtr, pidArray);
- for (i = 0; i < numMatched; i++) {
- status = (*actionFuncPtr)(pidArray[i]);
- if ((!ignoreStatus) && (status != SUCCESS)) {
- break;
- }
- }
- free((Address) pidArray);
- if (numMatchedPtr != (int *) NIL) {
- *numMatchedPtr = numMatched;
- }
- if (ignoreStatus) {
- return(SUCCESS);
- }
- return(status);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_SetServerPriority --
- *
- * Changes the priority of a server process to the non-interruptable
- * value. The pid is assumed to be valid.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The process's priority is changed.
- *
- *----------------------------------------------------------------------
- */
-
- void
- Proc_SetServerPriority(pid)
- Proc_PID pid;
- {
- Proc_GetPCB(pid)->billingRate = PROC_NO_INTR_PRIORITY;
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_GetHostIDs --
- *
- * Returns the sprite IDs corresponding to the machines on which
- * the current process is effectively executing and on which
- * it is physically executing. These hosts are called the virtualHost
- * and physicalHost, respectively. For an unmigrated process, these
- * two are identical.
- *
- * Results:
- * SUCCESS The call was successful.
- * SYS_ARG_NOACCESS The user arguments were not accessible.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- Proc_GetHostIDs(virtualHostPtr, physicalHostPtr)
- int *virtualHostPtr; /* Buffer to hold virtual host ID. */
- int *physicalHostPtr; /* Buffer to hold physical host ID. */
- {
-
- Proc_ControlBlock *procPtr;
- int host;
-
- if (physicalHostPtr != (int *) USER_NIL) {
-
- if (Vm_CopyOut(sizeof(int), (Address) &rpc_SpriteID,
- (Address) physicalHostPtr) != SUCCESS) {
- return(SYS_ARG_NOACCESS);
- }
- }
-
-
- if (virtualHostPtr != (int *) USER_NIL) {
- procPtr = Proc_GetCurrentProc();
- Proc_Lock(procPtr);
- host = procPtr->peerHostID;
- Proc_Unlock(procPtr);
- if (host == NIL) {
- host = rpc_SpriteID;
- }
- if (Vm_CopyOut(sizeof(int), (Address) &host,
- (Address) virtualHostPtr) != SUCCESS) {
- return(SYS_ARG_NOACCESS);
- }
- }
-
- return(SUCCESS);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_PushLockStack --
- *
- * Pushes the given lock type on the lock stack for the process.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Stuff is printed if the stack overflows.
- *
- *----------------------------------------------------------------------
- */
-
- /*ARGSUSED*/
- void
- Proc_PushLockStack(pcbPtr, type, lockPtr)
- Proc_ControlBlock *pcbPtr; /* ptr to pcb to modify */
- int type; /* type of lock */
- Address lockPtr; /* ptr to lock */
-
- {
- #ifdef LOCKDEP
- static Boolean firstOverflow = TRUE;
-
- /*
- * Modifying the lock stack of a process has to be an atomic operation,
- * but we don't want to use a lock to do this, since this is part of
- * the code used when locking or unlocking. Using a lock would lead
- * to a circularity and probably a deadlock. All we really need to
- * prevent is an interrupt handler from grabbing a lock while we're
- * modifying the lock stack. A process only modifies its own
- * lock stack, so turning off interrupts should be good enough.
- */
- DISABLE_INTR();
- if (pcbPtr->lockStackSize >= PROC_LOCKSTACK_SIZE) {
- if (firstOverflow) {
- printf("Proc_PushLockStack: stack overflow in pcb 0x%x.\n",pcbPtr);
- firstOverflow = FALSE;
- }
- goto exit;
- }
- if (pcbPtr->lockStackSize < 0 ) {
- printf("Proc_PushLockStack: stack underflow (%d) in pcb 0x%x.\n",
- pcbPtr->lockStackSize, pcbPtr);
- goto exit;
- }
- pcbPtr->lockStack[pcbPtr->lockStackSize].type = type;
- pcbPtr->lockStack[pcbPtr->lockStackSize].lockPtr = lockPtr;
- pcbPtr->lockStackSize++;
- exit:
- ENABLE_INTR();
- #endif
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Proc_RemoveFromLockStack --
- *
- * Removes the given lock from the stack if it is there.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- /*ARGSUSED*/
- void
- Proc_RemoveFromLockStack(pcbPtr, lockPtr)
- Proc_ControlBlock *pcbPtr; /* ptr to pcb to modify */
- Address lockPtr; /* ptr to lock */
- {
- #ifdef LOCKDEP
- int i;
- int stackTop;
- Boolean found = FALSE;
-
- DISABLE_INTR();
- if (pcbPtr->lockStackSize < 0) {
- ENABLE_INTR();
- panic("Lock stack underflow (1).\n");
- goto exit;
- }
- if (pcbPtr->lockStackSize == 0) {
- goto exit;
- }
- stackTop = pcbPtr->lockStackSize - 1;
- for (i = pcbPtr->lockStackSize - 1; i >= 0; i--) {
- if (pcbPtr->lockStack[i].lockPtr == lockPtr) {
- pcbPtr->lockStack[i].lockPtr = (Address) NIL;
- pcbPtr->lockStack[i].type = -1;
- found = TRUE;
- break;
- }
- }
- if (!found) {
- goto exit;
- }
- for (i = stackTop; i >= 0; i--) {
- if (pcbPtr->lockStack[i].lockPtr != (Address) NIL) {
- break;
- }
- }
- pcbPtr->lockStackSize = i + 1;
- if (pcbPtr->lockStackSize < 0) {
- printf("lockStackSize %d\n",pcbPtr->lockStackSize);
- }
- exit:
- ENABLE_INTR();
- #endif
- }
-
- #ifndef LOCKREG
- #ifndef CLEAN_LOCK
- #ifndef CLEAN
- /*
- *----------------------------------------------------------------------
- *
- * Proc_KDump --
- *
- * Prints out an (kluged) proc table with state information.
- *
- * This routine uses several macros to analyse the event data structure:
- * ISADDR(x) tests if x is a valid address.
- * ISSTR(x) tests if x is a pointer to a valid string.
- * ISALIGN(x) tests if x is an aligned address.
- * ISBOOL(x) tests if x is a boolean.
- * ISSMALL(x) tests is x is a small integer.
- * ISLIST(x) tests if x points to a List_Links structure.
- * ISPCB(x) tests if x points to a Proc_ControlBlock structure.
- * ISHANDLE(x) tests is x points to a Fs_HandleHeader structure.
- * FIELD(x,type,field) is x->type.field
- *
- * Results:
- * SUCCESS.
- *
- * Side effects:
- * Prints stuff to screen.
- *
- *
- *----------------------------------------------------------------------
- */
- #define INT(x) ((int)(x))
- #define INTP(x) ((int *)(x))
- #define ISADDRR(x,range) ((INT(x)&1)==0 && Dbg_InRange((unsigned)(x),2,FALSE)\
- && Dbg_InRange(((unsigned)(x))+(range)-2,2,FALSE))
- #define ISADDR(x) ISADDRR(x,sizeof(int))
- #define ISSTR(x) (ISADDRR(x,20) && \
- (strncpy(buf,(char *)(x),20),strlen(buf)<20) && isprint(buf[0]))
- #define ISSTRZ(x) (INT(x)==0 || ISSTR(x))
- #define ISALIGN(x) (ISADDR(x) && (INT(x)&3)==0)
- #define ISALIGNZ(x) (INT(x)==0 || ISALIGN(x))
- /* sun3 test-and-set sets to 0x80000000, sun4 to 0xff000000 */
- #define ISBOOL(x) (INT(x)==0||INT(x)==1||INT(x)==0x80000000||\
- INT(x)==0xff000000)
- #define ISSMALL(x) (INT(x)>=0&&INT(x)<20)
- #define ISPCBZ(x) (INT(x)==0||ISPCB(x))
- #define OFF(type,field) (INTP(&(((type *)0)->field))-INTP(0))
- #define FIELD(var,type,field) (((type *)(var))->field)
- #define P_cb Proc_ControlBlock
- #define Fc_b Fscache_Block
- #define Fc_fi Fscache_FileInfo
- #define F_hh Fs_HandleHeader
- #define L_L List_Links
- #define HANDLENAME(x) (Fsutil_HandleName((Fs_HandleHeader *)(x)))
- #define PRINTHANDLE(str,handle) printf("%s: \"%s\" (handle locked by %x)",\
- str, HANDLENAME(handle), handle->lockProcPtr)
- char buf[21] = {0};
-
- static int ISLIST(x)
- List_Links *x;
- {
- return ISADDRR(x,sizeof(List_Links)) && ISADDR(x->prevPtr) &&
- ISADDR(x->nextPtr);
- }
-
- static int ISPCB(x)
- Proc_ControlBlock *x;
- {
- return ISADDRR(x,sizeof(Proc_ControlBlock)) && ISLIST(&x->links) &&
- ISSMALL(x->processor) && ISLIST(&x->childListHdr) &&
- x->processID <= 0xfffff;
- }
-
- static int ISHANDLE(x)
- Fs_HandleHeader *x;
- {
- return ISADDRR(x,sizeof(Fs_HandleHeader)) && ISLIST(&x->lruLinks) &&
- ISBOOL(x->unlocked.waiting) && ISSMALL(x->refCount) &&
- ISSTRZ(x->name) &&
- (x->lockProcPtr == (Proc_ControlBlock *)NIL
- || ISPCB(x->lockProcPtr));
- }
-
- static int ISRPCCLIENT(x)
- RpcClientChannel *x;
- {
- int i;
- if (!ISADDRR(x,sizeof(RpcClientChannel))) return 0;
- for (i=0;i<rpcNumChannels;i++) {
- if (rpcChannelPtrPtr[i] == x) return 1;
- }
- return 0;
- }
-
- static int ISRPCSERVER(x)
- RpcServerState *x;
- {
- int i;
- if (!ISADDRR(x,sizeof(RpcServerState))) return 0;
- for (i=0;i<rpcMaxServers;i++) {
- if (rpcServerPtrPtr[i] == x) return 1;
- }
- return 0;
- }
-
- static int ISSERVERPROC(x)
- ServerInfo *x;
- {
- int i;
- if (!ISADDRR(x,sizeof(ServerInfo))) return 0;
- for (i=0;i<proc_NumServers;i++) {
- if (serverInfoTable+i == x) return 1;
- }
- return 0;
- }
-
- static int ISLOCK(x)
- Sync_Lock *x;
- {
- return ISADDRR(x,sizeof(Sync_Lock)) && ISBOOL(x->inUse) &&
- ISBOOL(x->waiting) && ISSTR(x->name) && ISALIGNZ(x->holderPC) &&
- ISPCBZ(x->holderPCBPtr);
- }
-
- static int ISSEM(x)
- Sync_Semaphore *x;
- {
- return ISADDRR(x,sizeof(Sync_Semaphore)) && ISSMALL(x->value) &&
- ISSTR(x->name) && ISALIGNZ(x->holderPC) && ISPCBZ(x->holderPCBPtr);
- }
-
- typedef struct LockEntry {
- int addr; /* Address (event) associated with the lock. */
- char *name; /* Name of the lock event. */
- } LockEntry;
-
- extern Sync_Condition cleanBlockCondition, writeBackComplete,
- closeCondition, lruDone, debugListCondition, familyCondition,
- migrateCondition, evictCondition, recovCondition, recovPingCondition,
- rpcDaemon, freeChannels, signalCondition, codeSegCondition,
- cleanCondition, swapDownCondition, mappingCondition, swapFileCondition;
-
- LockEntry locks[] = {
- (int)&cleanBlockCondition, "cleanBlockCondition",
- (int)&writeBackComplete, "writeBackComplete",
- (int)&closeCondition, "closeCondition",
- (int)&lruDone, "lruDone",
- (int)&debugListCondition, "debugListCondition",
- (int)&familyCondition, "familyCondition",
- (int)&migrateCondition, "migrateCondition",
- (int)&evictCondition, "evictCondition",
- (int)&recovCondition, "recovCondition",
- (int)&rpcDaemon, "rpcDaemon",
- (int)&freeChannels, "freeChannels",
- (int)&signalCondition, "signalCondition",
- (int)&codeSegCondition, "codeSegCondition",
- (int)&cleanCondition, "cleanCondition",
- (int)&swapDownCondition, "swapDownCondition",
- (int)&mappingCondition, "mappingCondition",
- (int)&swapFileCondition, "swapFileCondition",
- (int)&recovPingCondition, "recovPingCondition",
- 0, 0
- };
-
- /*ARGSUSED*/
- void
- Proc_KDump(dummy)
- ClientData dummy; /* unused - see dump.c:eventTable */
- {
- int i;
- Proc_ControlBlock *procPtr, *tmpProcPtr;
- int *event;
- LockEntry *lockPtr;
- Fscache_FileInfo *cacheInfoPtr;
- Fs_HandleHeader *handlePtr;
- RpcClientChannel *rpcClientPtr;
- RpcServerState *rpcServerPtr;
- ServerInfo *serverProcPtr;
- int match;
-
- for (i = 0; i < proc_MaxNumProcesses; i++) {
- procPtr = proc_PCBTable[i];
- match = 0;
- if (procPtr->state == PROC_WAITING) {
- printf("%8x", procPtr->processID);
- if (procPtr->argString != (Address) NIL) {
- char cmd[30];
- char *space;
-
- (void) strncpy(cmd, procPtr->argString, 30);
- space = strchr(cmd, ' ');
- if (space != (char *) NULL) {
- *space = '\0';
- } else {
- cmd[29] = '\0';
- }
- printf("(%s)", cmd);
- }
- printf(": waiting on ");
- event = (int *)procPtr->event;
- if (ISADDR(event)) {
- for (lockPtr = locks ; lockPtr->addr != 0; lockPtr++) {
- if ((int)event == lockPtr->addr) {
- printf("condition \"%s\"\n", lockPtr->name);
- goto found;
- }
- }
- if (ISLOCK((Sync_Lock *)event)) {
- /* Sync_Lock / Sync_KernelLock */
- printf("lock \"%s\" at %x", (char *)(event[2]),
- (int)event[3]);
- if (ISPCB((P_cb *)event[4])) {
- printf(" held by process %x",
- ((Proc_ControlBlock *)(event[4]))->processID);
- }
- } else if (ISPCB((P_cb *)event)) {
- /* Proc_ControlBlock */
- printf("timer %x",
- ((Proc_ControlBlock *)event)->processID);
- } else if (ISSEM((Sync_Semaphore *)event)) {
- /* Sync_Semaphore */
- printf("semaphore \"%s\" at %x",
- (char *)(event[1]), (int)(event[2]));
- if (ISPCB((P_cb *)event[3])) {
- printf(" held by process %x",
- ((Proc_ControlBlock *)(event[3]))->processID);
- }
- } else if (ISBOOL(event[0])) {
- /* Sync_Condition */
- handlePtr = (F_hh *)(event-OFF(F_hh,unlocked));
- if (ISHANDLE(handlePtr)) {
- PRINTHANDLE("handle: \"unlocked\"", handlePtr);
- match++;
- }
- handlePtr = (F_hh *)(FIELD(event-OFF(Fc_fi,noDirtyBlocks),
- Fc_fi, hdrPtr));
- if (ISHANDLE(handlePtr)) {
- PRINTHANDLE("cache block: \"noDirtyBlocks\"",
- handlePtr);
- match++;
- }
- /* See if intPtr is a cacheInfoPtr */
- cacheInfoPtr = (Fc_fi *)FIELD(event-OFF(Fc_b,ioDone), Fc_b,
- cacheInfoPtr);
- if (ISADDRR(cacheInfoPtr,sizeof(Fc_fi)) &&
- ISHANDLE(cacheInfoPtr->hdrPtr)) {
- PRINTHANDLE("cache block: \"ioDone\"",
- cacheInfoPtr->hdrPtr);
- match++;
- }
- tmpProcPtr = (P_cb *)(event-OFF(P_cb,waitCondition));
- if (ISPCB(tmpProcPtr)) {
- printf("PCB: \"waitCondition\" ");
- match++;
- }
- tmpProcPtr = (P_cb *)(event-OFF(P_cb,lockedCondition));
- if (ISPCB(tmpProcPtr)) {
- printf("PCB: \"lockedCondition\" ");
- match++;
- }
- serverProcPtr = (ServerInfo *)(event-
- OFF(ServerInfo, condition));
- if (ISSERVERPROC(serverProcPtr)) {
- printf("ServerProc: \"condition\" ");
- if (serverProcPtr->flags & ENTRY_INUSE) {
- printf("INUSE ");
- }
- if (serverProcPtr->flags & SERVER_BUSY) {
- printf("BUSY ");
- }
- if (serverProcPtr->flags & FUNC_PENDING) {
- printf("PENDING ");
- }
- match++;
- }
- rpcClientPtr = (RpcClientChannel *)(event-
- OFF(RpcClientChannel, waitCondition));
- if (ISRPCCLIENT(rpcClientPtr)) {
- printf("RPC client: \"waitCondition\", server %d ",
- rpcClientPtr->serverID);
- if (rpcClientPtr->state & CHAN_FREE) printf("FREE ");
- if (rpcClientPtr->state & CHAN_BUSY) printf("BUSY ");
- if (rpcClientPtr->state & CHAN_WAITING) printf("WAIT ");
- if (rpcClientPtr->state & CHAN_TIMEOUT) printf("TIME ");
- if (rpcClientPtr->state & CHAN_FRAGMENTING) {
- printf("FRAG ");
- }
- match++;
- }
- rpcServerPtr = (RpcServerState *)(event-
- OFF(RpcServerState, waitCondition));
- if (ISRPCSERVER(rpcServerPtr)) {
- printf("RPC server:\"waitCondition\", client %d ",
- rpcServerPtr->clientID);
- if (rpcServerPtr->state & SRV_NOTREADY) {
- printf("NOTREADY ");
- }
- if (rpcServerPtr->state & SRV_FREE) printf("FREE ");
- if (rpcServerPtr->state & SRV_BUSY) printf("BUSY ");
- if (rpcServerPtr->state & SRV_WAITING) printf("WAIT ");
- if (rpcServerPtr->state & SRV_AGING) printf("AGING ");
- if (rpcServerPtr->state & SRV_FRAGMENT) printf("FRAG ");
- if (rpcServerPtr->state & SRV_NO_REPLY) {
- printf("NO_REPLY ");
- }
- if (rpcServerPtr->state & SRV_STUCK) printf("STUCK ");
- match++;
- }
- handlePtr = (F_hh *)(event-OFF(Fsrmt_IOHandle,
- recovery.reopenComplete));
- if (ISHANDLE(handlePtr)) {
- PRINTHANDLE("\"recovery.reopenComplete\"", handlePtr);
- match++;
- }
- if (!match) {
- printf("condition %x", (int)event);
- } else if (match>1) {
- printf("(Ambiguous)");
- }
- } else {
- printf("event %x", (int)event);
- }
- } else if ((int)event == -1) {
- printf("wakeup signal");
- } else {
- printf("event? %x", (int)event);
- }
- printf("\n");
- found:;
- }
- }
- }
- #define KDUMP
- #endif
- #endif
- #endif
-
- #ifndef KDUMP
- /* ARGSUSED */
- ReturnStatus
- Proc_KDump(dummy)
- ClientData dummy;
- {
- return SUCCESS;
- }
- #endif
-